package com.lightjet.macross.base.upms.controller;

import com.lightjet.macross.base.feign.api.controller.PrincipalController;
import com.lightjet.macross.base.feign.api.domain.AuthRole;
import com.lightjet.macross.base.feign.api.domain.AuthUser;
import com.lightjet.macross.base.upms.domain.SysOrganization;
import com.lightjet.macross.base.upms.domain.SysUser;
import com.lightjet.macross.base.upms.service.LoginAdapterService;
import com.lightjet.macross.base.upms.service.RoleUserLinkService;
import com.lightjet.macross.base.upms.service.SysUserService;
import com.lightjet.macross.common.dto.ResponseDTO;
import com.lightjet.macross.common.util.MD5Util;
import com.lightjet.macross.common.util.RespUtil;
import com.lightjet.macross.common.util.SpringUtil;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.*;
import lombok.extern.java.Log;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.List;

/**
 * @author : lijia
 * @version : 1.0 2019-10-28 12:55
 * description : 用户管理控制器
 */

@RestController
@RequestMapping("/api/user")
@Scope("request")
@Log
@RefreshScope
@Api(tags="通用系统权限管理-默认体系用户相关接口集")
public class UserController extends PrincipalController  {
    @Value("${biz.caption}")
    private String caption;

    @Value("${biz.usersystembeanname:macross}")
    private String usersystembeanname;

    @Resource
    private SysUserService userViewService;

    @Resource(name="macross")
    private LoginAdapterService loginAdapterService;

    @Resource
    private RoleUserLinkService roleUserLinkService;


    @RequestMapping(value = "/current", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "当前用户信息接口", notes = "返回通过Token获取的当前认证用户信息")
    //@PreAuthorize("hasRole('SYSADMIN')")
    //@Override
    public ResponseDTO<SysUser> Current(@ApiIgnore @ModelAttribute("CurrentUser") AuthUser user) {
/*        for(GrantedAuthority authRole : user.getAuthorities())
        {
            System.out.println(authRole.getAuthority());
        }*/
        return RespUtil.CreateOK(userViewService.FromAuthUser(user));
    }

    @GetMapping(value = "")
    @ApiOperation(value = "单体用户数据接口", notes = "根据用户ID、用户名的优先级查找唯一的用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name="id",value = "用户ID",paramType = "query"),
            @ApiImplicitParam(name="username",value = "用户名",paramType = "query")
    })
    public ResponseDTO<SysUser> GetUser(String id, String username) {
        SysUser userView =null;
        if(!StringUtil.isNullOrEmpty(id))
        {
            userView = userViewService.FindDistinctById(id);

        }
        if(userView==null&&!StringUtil.isNullOrEmpty(username))
        {
            userView = userViewService.FindDistinctByUsername(username);
        }
        if(userView == null)
        {
            userView = new SysUser(id,"未知用户["+id+"]");
        }
        return RespUtil.CreateOK(userView);
    }

    @PostMapping(value = "",consumes = "application/json")
    @ApiOperation(value = "单体用户创建接口", notes = "根据用户用户Json创建系统用户")
    public ResponseDTO<SysUser> UserCreate(
            @ApiParam(name = "sysUser",
                    value = "用户实体类Json",
                    type="body") @RequestBody SysUser sysUser)
    {
        return RespUtil.CreateOK(userViewService.Create(sysUser));
    }

    @PutMapping(value = "",consumes = "application/json")
    @ApiOperation(value = "单体用户更新接口", notes = "根据用户Json更新系统用户")
    public ResponseDTO<SysUser> UserUpdate(
            @ApiParam(name = "sysUser",
                    value = "用户实体类Json",
                    type="body") @RequestBody SysUser sysUser)
    {
        SysUser original = userViewService.FindDistinctById(sysUser.getId());
        original.setDisplayname(sysUser.getDisplayname());
        original.setUsername(sysUser.getUsername());
        original.setEmail(sysUser.getEmail());
        original.setMobile(sysUser.getMobile());
        if(sysUser.getAffiliation()!=null && sysUser.getAffiliation().getId()!=null)
        {
            original.setAffiliation(new SysOrganization(sysUser.getAffiliation().getId()));
        }
        if(!StringUtil.isNullOrEmpty(sysUser.getPassword()))
        {
            original.setPassword(MD5Util.Encode(sysUser.getPassword(), original.getSalt()));
        }
        return RespUtil.CreateOK(userViewService.UpdateAndFlush(original));
    }

    @DeleteMapping(value = "/batch", consumes = "application/json")
    @ApiOperation(value = "批量删除用户接口", notes = "根据用户ID列表Json批量删除")
    public ResponseDTO<String> UserDeleteBatch(
            @ApiParam(name = "ids",value = "用户ID List Json形式",type="body") @RequestBody List<String> ids)
    {
        StringBuilder sb = new StringBuilder();
        for(String id : ids)
        {
            try
            {
                userViewService.DeleteOne(new SysUser(id));
            }
            catch (Exception e)
            {
                sb.append(MessageFormat.format("删除用户【{0}】删除失败：{1};",id,e.getMessage()));
            }
        }
        if(sb.length()>0)
        {
            return RespUtil.CreateError(sb.toString());
        }
        else
        {
            return RespUtil.CreateOK();
        }
    }

    @RequestMapping(value = "/adapter", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "单体用户数据接口(根据用户体系获取)", notes = "根据用户ID查找唯一的用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name="id",value = "用户ID",paramType = "query"),
            @ApiImplicitParam(name="beanname",value = "用户体系处理类beanname 默认（macross平台用户）",paramType = "query")
    })
    public ResponseDTO<AuthUser> GetUserBySystem(String id,String beanname) {
        AuthUser retUser = new AuthUser();
        retUser.setDisplayname("未知用户["+id+"]");
        beanname = StringUtil.isNullOrEmpty(beanname)?usersystembeanname:usersystembeanname;
        loginAdapterService = SpringUtil.getBean(beanname, LoginAdapterService.class);
        if(!StringUtil.isNullOrEmpty(id))
        {
            retUser = loginAdapterService.GetByUserKey(id);

        }
        return RespUtil.CreateOK(retUser);
    }

    @RequestMapping(value = "/all", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "所有用户数据接口", notes = "获取所有用户信息")
    //@Override
    public ResponseDTO<List<SysUser>> GetAllUsers() {
        return RespUtil.CreateOK(userViewService.FindAll());
    }

    @RequestMapping(value = "/dept", method = {RequestMethod.POST, RequestMethod.GET})
    //@Override
    @ApiOperation(value = "部门用户数据接口", notes = "根据部门ID获取部门所有用户，若参数为空则获取当前用户所在部门用户集合")
    @ApiImplicitParams({
            @ApiImplicitParam(name="deptid",value = "部门ID",paramType = "query")
    })
    public ResponseDTO<List<SysUser>> GetUsersByDeptId(String id, @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user) {
        if(StringUtil.isNullOrEmpty(id))
        {
            id = user.getOrgid();
        }
        SysUser example = new SysUser();
        example.setAffiliation(new SysOrganization(id));
        return RespUtil.CreateOK(userViewService.FindAll(Example.of(example)));
    }

    @GetMapping(value = "/query")
    public ResponseDTO<List<SysUser>> QueryByFilter(String username,String displayname, String email,String mobile)
    {
        username = StringUtil.isNullOrEmpty(username)?"%%":"%"+username+"%";
        displayname = StringUtil.isNullOrEmpty(displayname)?"%%":"%"+displayname+"%";
        email = StringUtil.isNullOrEmpty(email)?"%%":"%"+email+"%";
        mobile = StringUtil.isNullOrEmpty(mobile)?"%%":"%"+mobile+"%";
        return RespUtil.CreateOK(userViewService.FindByFilters(username,displayname,email,mobile));
    }

    @RequestMapping(value = "/page", method = {RequestMethod.POST, RequestMethod.GET})
    //@Override
    @ApiOperation(value = "批量用户分页数据接口", notes = "根据筛选条件获取分页的用户信息集合")
    @ApiImplicitParams({
            @ApiImplicitParam(name="dispname",value = "用户显示名",paramType = "query"),
            @ApiImplicitParam(name="uname",value = "用户名",paramType = "query"),
            @ApiImplicitParam(name="workno",value = "工号",paramType = "query"),
            @ApiImplicitParam(name="deptid",value = "部门ID",paramType = "query"),
            @ApiImplicitParam(name="pageSize",value = "分页大小",paramType = "query"),
            @ApiImplicitParam(name="pageNumber",value = "当前页",paramType = "query")
    })
    public ResponseDTO<Page<SysUser>> GetUsersPagedByFilters(String dispname, String uname, String workno, String deptid, Integer pageSize, Integer pageNumber) {
        Pageable pageable = PageRequest.of(pageNumber, pageSize);
        dispname = dispname == null?"":dispname;
        uname = uname==null?"":uname;
        workno = workno==null?"":workno;
        deptid = deptid==null?"-1":deptid;
        return RespUtil.CreateOK(userViewService.FindPagedByFilters("%"+uname+"%","%"+dispname+"%","%"+workno+"%",deptid,pageable));
    }

    //@Override
    @RequestMapping(value = "/role", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "角色下属用户接口", notes = "根据角色、角色所在系统以及部门等信息获取用户信息集合")
    @ApiImplicitParams({
            @ApiImplicitParam(name="systemshortname",value = "系统简称",paramType = "query",required = true),
            @ApiImplicitParam(name="deptid",value = "部门ID（-1 代表查全部）",paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name="rolecode",value = "角色代号（* 代表查全部 优先级高于角色名称参数，不区分大小写）",paramType = "query"),
            @ApiImplicitParam(name="rolename",value = "角色名称（* 代表查全部 角色代号不为*时该参数无效）",paramType = "query"),
            @ApiImplicitParam(name="exchange-token",value = "认证Header头信息（JWT格式）",paramType = "header")
    })
    public ResponseDTO<List<SysUser>> GetUsersByRole(String systemshortname, Integer deptid, String rolecode, String rolename) {
        deptid = deptid ==null?-1:deptid;
        rolecode = StringUtil.isNullOrEmpty(rolecode)?"*":rolecode;
        rolename = "*".equals(rolecode)? rolename:"*";
        return RespUtil.CreateOK(roleUserLinkService.FindBySystemAndDeptAndRole(systemshortname,deptid,rolecode,rolename));
    }

}
